#include "Task.h"

Task::~Task()
{
	Log->info("~Task");
}

boost::function<void ()> Task::getFunction()
{
	return mFunc;
}

TaskExecutor::TaskExecutor(size_t nThreads):mShutdown(false)
{

	size_t _i;

	for( _i=0 ; _i<=nThreads; _i++)
		mThreads.push_back(new boost::thread(&TaskExecutor::runThread,this));

}

TaskExecutor::~TaskExecutor()
{

}

void TaskExecutor::addTask(Task* task)
{
	mListMux.lock();
	if(!mShutdown)
	{
		//Log->info("[TaskEx]Adding task to list");
		mTaskList.push_back(task);
		mLoopCond.notify_all();
	}
	mListMux.unlock();
}

void TaskExecutor::runThread()
{

	boost::interprocess::interprocess_mutex _muxLoop;
	boost::interprocess::scoped_lock<boost::interprocess::interprocess_mutex> _loopLock(_muxLoop);

	while(!mShutdown)
	{

		while( mTaskList.empty() && !mShutdown )
		{
			//Log->info("[TaskEx]Waiting for tasks...");
			mLoopCond.wait(_loopLock);
		}

		mListMux.lock();

		Task* _listedTask = NULL;

		if( !mTaskList.empty() )
		{

			//Log->info("[TaskEx]Got new task",boost::this_thread::get_id);
			_listedTask = mTaskList.front();
			mTaskList.pop_front();

		}

		mListMux.unlock();

		if( _listedTask )
		{
			// Ejecutamos la tarea
			(*_listedTask)();
			delete _listedTask;
			Sleep(1000);
		}

	}

	//Log->info("[TaskEx]Thread finished");

}

void TaskExecutor::stop()
{

	size_t _i;

	mShutdown = true;
	mLoopCond.notify_all();

	for( _i=0 ; _i<mThreads.size(); _i++)
		mThreads[_i]->join();


}